
/*
    * 创建时间:  2022/10/24  今天是程序员节
    * 创建作者:  kris
    * 内容介绍:  封装简易版的axios
*/

/*
    axios({
        methods: 'GET',
        url: '',
        params: {},
        data: {}
    })
        .then(res => {
            console.log(res)
        })
        .catch(err => {
            console.log(err)
        })
*/


// 1. 解构字段使用 - 并且指定默认值
function axios({ methods = 'GET', url, params = {}, data = {} }) {

    // 2. 处理默认参数
    methods = methods.toUpperCase() || 'GET';
    // 2.1 前端的查询参数一般都会放在 params 里面
    // { count: 10, app_id: 'aszxgc' }  =>  count=10&app_id=aszxgc
    let queryStr = '';
    for (const k in params) {
        // queryStr += k + '=' + params[k] + '&'
        queryStr += `${k}=${params[k]}&`
    }
    // 2.2 判断查询参数不为空就给地址添加
    if (queryStr) {
        url += '?' + queryStr.slice(0, -1);
    }

    // 3. 如果需要结果能够使用 then 或者 catch ，就得返回一个 promsie 的实例
    return new Promise((resolve, reject) => {
        // 3.1 创建异步对象
        const xhr = new XMLHttpRequest();

        // 3.2 编辑请求行
        xhr.open(methods, url);

        // 3.3 设置响应的类型
        xhr.responseType = 'json';

        // 3.4 设置监听的事件
        xhr.onreadystatechange = function () {
            // 3.4.1 设置前端请求状态
            if (xhr.readyState !== 4) return

            // 3.4.2 判断后端的响应状态码
            const { status, statusText, response } = xhr;
            if (status >= 200 && status < 300 || status === 304) {
                // 3.5 表示成功的话，就直接改变成功的状态
                resolve({ data: response, status, statusText })
            } else reject(new Error('请求失败，报错状态为：' + status))
        }

        // 3.6 如果是post请求需要指定请求体并发送
        if (methods === 'POST' || methods === 'PUT') {
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.send(JSON.stringify(data));
        } else {
            xhr.send(null);
        }
    })
}